var CommonSearchForm = function () {
  var dropdownDictionary = {
    materialName: "物料名称",
    materialType: "物料类型",
    machining: "加工对象",
    model: "规格型号",
    color: "编号",
    colorDescription: "描述",
    providerName: "供应商",
    factoryNo: "工厂型号",
    factoryId: "工厂型号",
    orderId: "系统订单编号",
    companyOrderId: "订单编号",
    customerNo: "客户型号",
    coustomId: "客户型号",
    customerId: "客户型号",
    coustomOrderId: "客户订单号",
    customerOrderId: "客户订单号",
    customer: "客户",
    providerNo: "供方编号",
    materialDept: "物料部门",
    outOrderDept: "订单部门"
  };

  var selectDropdownOption = {
    materialDept: {
      valueField: "materialDeptId",
      labelField: "materialDeptName"
    },
    outOrderDept: {
      valueField: "deptId",
      labelField: "deptName"
    }
  };

  var CommonAutocomplete = function () {
    var template = /* html */ `
      <el-autocomplete ref="commonInput" v-model="showValue" :value-key="valueKey" :placeholder="placeholder" :size="size" :fetch-suggestions="fetchSuggestionsMethod"
        @change="handleChange"></el-autocomplete>
    `;

    return {
      props: {
        value: {
          required: true
        },
        placeholder: {
          type: String,
          default: ''
        },
        valueKey: {
          type: String,
          default: 'value'
        },
        fetchSuggestions: {
          type: Function,
          required: true
        },
        size: String
      },

      watch: {
        value: function () {
          if (this.inputValue !== null) {
            this.inputValue = null;
            return;
          }
          this.showValue = this.value;
        }
      },

      data: function () {
        return {
          showValue: this.value,
          inputValue: null,
          options: []
        };
      },

      methods: {
        fetchSuggestionsMethod: function (queryValue, cb) {
          var fetchSuggestions = this.fetchSuggestions;
          var valueKey = this.valueKey;
          var self = this;
          fetchSuggestions(queryValue).then(function (dropdownData) {
            var dropdownList = [];
            for (var i = 0; i < dropdownData.length; i++) {
              var data = dropdownData[i];
              var value = data[valueKey];
              if (typeof value === 'string') {
                if (value.trim() === '') {
                  continue;
                }
              }
              var obj = {};
              obj[valueKey] = value;
              dropdownList.push(obj);
            }
            self.options = dropdownList;
            cb(dropdownList);
          });
        },

        handleChange: function () {
          var value = this.showValue;
          this.inputValue = value;
          this.$emit('input', value);
          this.$emit('change', value);
        },

        clearSuggestions: function () {
          var options = this.options;
          if (options.length > 0) {
            this.$refs['commonInput'].clearSuggestions();
            this.options = [];
          }
        }
      },

      template: template
    };
  }();

  var CommonSelect = function () {
    var template = /* html */ `
      <el-select clearable filterable remote ref="commonInput" v-model="showValue" :value-key="item.valueField" :placeholder="placeholder"
        :size="size" :remote-method="remoteMethod" :loading="loading" @visible-change="visibleChange" @change="handleChange">
        <template v-if="visible">
          <el-option v-for="showOption in options" :key="'item_'+showOption[item.valueField]" :value="showOption" :label="showOption[item.labelField]">
          </el-option>
        </template>
        <template v-else-if="showValue!==''">
          <el-option :value="showValue" :label="showValue[item.labelField]"></el-option>
        </template>
      </el-select>
    `;

    return {
      props: {
        value: {
          required: true
        },
        placeholder: {
          type: String,
          default: ''
        },
        item: {
          type: Object,
          required: true
        },
        filterMethod: {
          type: Function,
          required: true
        },
        size: String
      },

      watch: {
        value: function () {
          if (this.inputValue !== null) {
            this.inputValue = null;
            return;
          }
          this.showValue = this.value;
        }
      },

      data: function () {
        return {
          loading: false,
          showValue: this.value,
          inputValue: null,
          options: [],
          visible: false,
          searchValue: null
        }
      },

      methods: {
        remoteMethod: function (queryValue, isInit) {
          if (this.searchValue === queryValue) {
            return;
          }
          this.searchValue = queryValue;
          var item = this.item;
          var filterMethod = this.filterMethod;
          var valueField = item.valueField,
            labelField = item.labelField;
          var self = this;
          this.loading = true;
          filterMethod(queryValue, item).then(function (dropdownData) {
            var dropdownList = [];
            for (var i = 0; i < dropdownData.length; i++) {
              var data = dropdownData[i];
              if (SysUtil.isEmpty(data)) {
                continue;
              }
              var value = data[valueField];
              var label = data[labelField];
              if (SysUtil.isEmpty(value) || SysUtil.isEmpty(label)) {
                continue;
              }

              var obj = {};
              obj[valueField] = value;
              obj[labelField] = label;
              dropdownList.push(obj);
            }

            var showValue = self.showValue;
            if (isInit && dropdownData.length === 0 && showValue !== '') {
              dropdownList.push(showValue);
            }
            self.options = dropdownList;
            self.loading = false;
          });
        },

        visibleChange: function (visible) {
          this.visible = visible;
          if (visible) {
            var showValue = this.showValue;
            var value = '';
            if (showValue !== '') {
              value = showValue[this.item.labelField];
            }
            this.remoteMethod(value, true);
          } else {
            this.searchValue = null;
          }
        },

        handleChange: function () {
          var value = this.showValue;
          this.inputValue = value;
          this.$emit('input', value);
          this.$emit('change', value);
        }
      },

      template: template
    };
  }();

  var template = /* html */ `
    <el-form class="common-search-form clearfix" :inline="inline" :label-width="labelWidth" :model="search" :size="size" v-loading.fullscreen.lock="loading">
      <slot name="prepend"></slot>
      <template v-for="item in formSearchField">
        <el-form-item :key="item.field" :label="dropdownDictionary[item.field]">
          <common-autocomplete v-if="item.type==='autocomplete'" :ref="'input_'+item.field" class="search-input" v-model="search[item.field]" :value-key="item.field"
            :placeholder="'请输入'+dropdownDictionary[item.field]" :style="{width:inputWidth}"
            :fetch-suggestions="function(queryValue){return fetchSuggestionsMethod(queryValue,item)}">
          </common-autocomplete>
          <common-select v-else-if="item.type==='select'" :ref="'input_'+item.field" v-model="search[item.field]" :item="item" :style="{width:inputWidth}"
            :placeholder="'请选择'+dropdownDictionary[item.field]" :filter-method="filterMethod"></common-select>
        </el-form-item>
      </template>
      <slot name="append"></slot>
    </el-form>
  `;

  return {
    inject: {
      btnView: {
        default: null
      }
    },

    props: {
      search: {
        type: Object,
        required: true
      },
      requestUrl: {
        type: String,
        default: ''
      },
      requestData: {
        type: Object,
        default: function () {
          return {};
        }
      },
      labelWidth: {
        type: String,
        default: undefined
      },
      inputWidth: {
        type: String,
        default: undefined
      },
      responseFilterFun: {
        type: Function,
        default: undefined
      },
      inline: {
        type: Boolean,
        default: true
      },
      size: String,
      dropdownProps: Object,
      searchField: {
        type: Array,
        default: function () {
          return [];
        }
      }
    },

    data: function () {
      var dropdownProps = this.dropdownProps;
      var dropdown = _.cloneDeep(dropdownDictionary);
      if (dropdownProps !== undefined) {
        dropdown = _.assignIn(dropdown, dropdownProps);
      }
      var formSearchField = [];
      var searchField = this.searchField;
      for (var i = 0; i < searchField.length; i++) {
        var field = searchField[i];
        var obj = {
          field: field
        };
        var option = selectDropdownOption[field];
        var type;
        if (option !== undefined) {
          _.assign(obj, option);
          type = "select";
        } else {
          type = "autocomplete";
        }
        obj.type = type;
        formSearchField.push(obj);
      }
      return {
        loading: false,
        dropdownData: [],
        dropdownDictionary: dropdown,
        formSearchField: formSearchField
      };
    },

    methods: {
      fetchSuggestionsMethod: function (queryValue, item) {
        return this.getDropdownData(queryValue, item).then(function (dropdownData) {
          return dropdownData;
        });
      },

      filterMethod: function (queryValue, item) {
        return this.getDropdownData(queryValue, item).then(function (dropdownData) {
          return dropdownData;
        });
      },

      getDropdownData: function (queryValue, item) {
        var formSearchField = this.formSearchField;
        var search = this.search;
        var filterObj = {};
        for (var i = 0; i < formSearchField.length; i++) {
          var fieldObj = formSearchField[i];
          var field = '',
            value = '';
          if (fieldObj.type === 'autocomplete') {
            field = fieldObj.field;
            if (item.field === fieldObj.field) {
              value = queryValue;
            } else {
              value = search[field];
            }
          } else {
            field = fieldObj.labelField;
            if (item.field === fieldObj.field) {
              value = queryValue;
            } else {
              var obj = search[fieldObj.field];
              if (!SysUtil.isEmpty(obj)) {
                value = obj[fieldObj.labelField];
              }
            }
          }
          filterObj[field] = value;
        }

        var requestData = this.requestData;
        postData = _.cloneDeep(requestData);
        postData.searchInput = item.type === 'autocomplete' ? item.field : item.labelField;
        for (var key in filterObj) {
          var value = filterObj[key];
          if (SysUtil.isEmpty(value)) {
            continue;
          }
          postData[key] = value;
        }
        var url = this.requestUrl;
        return ajaxRequest(url, postData).then(function (dropdownData) {
          return dropdownData;
        });
      },

      clearList: function () {
        this.clearSuggestions();
      },

      clearSuggestions: function () {
        var formSearchField = this.formSearchField;
        for (var i = 0; i < formSearchField.length; i++) {
          var searchField = formSearchField[i];
          if (searchField.type === 'select') {
            continue;
          }
          var field = searchField.field;
          this.$refs[`input_${field}`][0].clearSuggestions();
        }
      }
    },

    components: {
      CommonAutocomplete: CommonAutocomplete,
      CommonSelect: CommonSelect
    },

    template: template
  };
}();
